//
//  ESLinkedList.h
//  utils
//
//  Created by easy on 11-12-8.
//  Copyright 2011 zeasy@qq.com. All rights reserved.
//

#import <Foundation/Foundation.h>

@class ESLinkedList,ESLinkedListNode;

@protocol ESLinkedListDelegate <NSObject>
-(void) linkedList:(ESLinkedList *) list addedNode:(ESLinkedListNode *) node;
-(void) linkedList:(ESLinkedList *) list removedNode:(ESLinkedListNode *) node;
-(void) linkedList:(ESLinkedList *) list replaceNode:(ESLinkedListNode *) node withNode:(ESLinkedListNode *) toNode;
@end

@interface ESLinkedListNode : NSObject {
	ESLinkedListNode *_previousNode;
	ESLinkedListNode *_nextNode;
	
	id _value;
	@package
	ESLinkedList *_linkedList;
}
@property (nonatomic, readonly) ESLinkedList *linkedList;
@property (nonatomic, readonly) ESLinkedListNode *previousNode;
@property (nonatomic, readonly) ESLinkedListNode *nextNode;
@property (nonatomic, readonly) id value;

-(id) initWithValue:(id) value;
+(id) nodeWithValue:(id) value;
@end


@interface ESLinkedList : NSObject {
	ESLinkedListNode *_headNode;
	ESLinkedListNode *_tailNode;
	
	NSUInteger _count;
	
	id<ESLinkedListDelegate> _delegate;
}

@property (nonatomic, readonly) ESLinkedListNode *headNode;
@property (nonatomic, readonly) ESLinkedListNode *tailNode;
@property (nonatomic, assign) id<ESLinkedListDelegate> delegate;

-(NSUInteger) count;

-(id) initWithHeadNode:(ESLinkedListNode *) headNode tailNode:(ESLinkedListNode *) tailNode;
-(id) initWithHeadNode:(ESLinkedListNode *) headNode;
-(id) initWithTailNode:(ESLinkedListNode *) tailNode;
-(id) init;

-(BOOL) addNode:(ESLinkedListNode *) node beforeNode:(ESLinkedListNode *) beforeNode;
-(BOOL) addNode:(ESLinkedListNode *) node afterNode:(ESLinkedListNode *) afterNode;
-(BOOL) addNode:(ESLinkedListNode *)node atIndex:(NSUInteger) index;

-(BOOL) removeNode:(ESLinkedListNode *) node;
-(BOOL) removeNodeAtIndex:(NSUInteger) index;

-(BOOL) replaceNode:(ESLinkedListNode *) node withNode:(ESLinkedListNode *) toNode;
-(BOOL) replaceNodeAtIndex:(NSUInteger) index withNode:(ESLinkedListNode *) node;

-(ESLinkedListNode *) nodeAtIndex:(NSUInteger) index;
-(NSUInteger) indexOfObject:(id) object;
-(NSUInteger) indexOfNode:(ESLinkedListNode *) node;

//双端链表
-(BOOL) addFirst:(ESLinkedListNode *) node;
-(BOOL) addLast:(ESLinkedListNode *) node;
-(BOOL) removeFirst;
-(BOOL) removeLast;

//for queue
-(BOOL) offerNode:(ESLinkedListNode *) node;
-(ESLinkedListNode *) peekNode;
-(ESLinkedListNode *) pollNode;

//array
-(NSArray *) allValues;
-(NSArray *) allNodes;
@end
